; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -codegenprepare -cgp-optimize-phi-types %s -S | FileCheck %s

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnu"

define float @convphi1(i32 *%s, i32 *%d, i32 %n) {
; CHECK-LABEL: @convphi1(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load i32, i32* %s, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi2(i32 *%s, i32 *%d, i32 %n) {
; CHECK-LABEL: @convphi2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ undef, %entry ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi3(i32 *%s, i32 *%d, i32 %n, float %f) {
; CHECK-LABEL: @convphi3(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ [[F:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  %fb = bitcast float %f to i32
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define void @convphi4(i32 *%s, i32 *%d, i32 %n, float %f) {
; CHECK-LABEL: @convphi4(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ [[F:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[PHI_TC]] to i32
; CHECK-NEXT:    store i32 [[BC]], i32* [[D:%.*]], align 4
; CHECK-NEXT:    ret void
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  %fb = bitcast float %f to i32
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
  store i32 %phi, i32 *%d
  ret void
}

define i64 @convphi_d2i(double *%s, double *%d, i32 %n) {
; CHECK-LABEL: @convphi_d2i(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load double, double* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast double [[LS]] to i64
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load double, double* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast double [[LD]] to i64
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi i64 [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    ret i64 [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load double, double* %s, align 4
  br label %end

else:
  %ld = load double, double* %d, align 4
  br label %end

end:
  %phi = phi double [ %ls, %then ], [ %ld, %else ]
  %b = bitcast double %phi to i64
  ret i64 %b
}

define i32 @convphi_f2i(float *%s, float *%d, i32 %n) {
; CHECK-LABEL: @convphi_f2i(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load float, float* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast float [[LS]] to i32
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load float, float* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast float [[LD]] to i32
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi i32 [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    ret i32 [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load float, float* %s, align 4
  br label %end

else:
  %ld = load float, float* %d, align 4
  br label %end

end:
  %phi = phi float [ %ls, %then ], [ %ld, %else ]
  %b = bitcast float %phi to i32
  ret i32 %b
}

define i16 @convphi_h2i(half *%s, half *%d, i32 %n) {
; CHECK-LABEL: @convphi_h2i(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load half, half* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast half [[LS]] to i16
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load half, half* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast half [[LD]] to i16
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi i16 [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    ret i16 [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load half, half* %s, align 4
  br label %end

else:
  %ld = load half, half* %d, align 4
  br label %end

end:
  %phi = phi half [ %ls, %then ], [ %ld, %else ]
  %b = bitcast half %phi to i16
  ret i16 %b
}

define i128 @convphi_ld2i(fp128 *%s, fp128 *%d, i32 %n) {
; CHECK-LABEL: @convphi_ld2i(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load fp128, fp128* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast fp128 [[LS]] to i128
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load fp128, fp128* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast fp128 [[LD]] to i128
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi i128 [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    ret i128 [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load fp128, fp128* %s, align 4
  br label %end

else:
  %ld = load fp128, fp128* %d, align 4
  br label %end

end:
  %phi = phi fp128 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast fp128 %phi to i128
  ret i128 %b
}

define <4 x i32> @convphi_4xf2i(<4 x float> *%s, <4 x float> *%d, i32 %n) {
; CHECK-LABEL: @convphi_4xf2i(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load <4 x float>, <4 x float>* [[S:%.*]], align 4
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load <4 x float>, <4 x float>* [[D:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi <4 x float> [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
; CHECK-NEXT:    [[B:%.*]] = bitcast <4 x float> [[PHI]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[B]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load <4 x float>, <4 x float>* %s, align 4
  br label %end

else:
  %ld = load <4 x float>, <4 x float>* %d, align 4
  br label %end

end:
  %phi = phi <4 x float> [ %ls, %then ], [ %ld, %else ]
  %b = bitcast <4 x float> %phi to <4 x i32>
  ret <4 x i32> %b
}

define float @convphi_loop(i32 *%s, i32 *%d, i64 %n) {
; CHECK-LABEL: @convphi_loop(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i64 [[N:%.*]], 0
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br i1 [[CMP15]], label [[LOOP:%.*]], label [[END:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT:    [[LPHI_TC:%.*]] = phi float [ [[LS_BC]], [[ENTRY]] ], [ [[LD_BC:%.*]], [[LOOP]] ]
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[END]], label [[LOOP]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ undef, [[ENTRY]] ], [ [[LPHI_TC]], [[LOOP]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i64 %n, 0
  %ls = load i32, i32* %s, align 4
  br i1 %cmp15, label %loop, label %end

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %lphi = phi i32 [ %ls, %entry ], [ %ld, %loop ]
  %ld = load i32, i32* %d, align 4
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond = icmp eq i64 %iv.next, %n
  br i1 %exitcond, label %end, label %loop

end:
  %phi = phi i32 [ undef, %entry ], [ %lphi, %loop ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi_loopdelayed(i32 *%s, i32 *%d, i64 %n) {
; CHECK-LABEL: @convphi_loopdelayed(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i64 [[N:%.*]], 0
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    br i1 [[CMP15]], label [[LOOP:%.*]], label [[END:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[END]], label [[LOOP]]
; CHECK:       end:
; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    ret float [[B]]
;
entry:
  %cmp15 = icmp sgt i64 %n, 0
  %ls = load i32, i32* %s, align 4
  br i1 %cmp15, label %loop, label %end

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %lphi = phi i32 [ %ls, %entry ], [ %lphi, %loop ]
  %ld = load i32, i32* %d, align 4
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond = icmp eq i64 %iv.next, %n
  br i1 %exitcond, label %end, label %loop

end:
  %phi = phi i32 [ undef, %entry ], [ %lphi, %loop ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi_loopdelayed2(i32 *%s, i32 *%d, i64 %n) {
; CHECK-LABEL: @convphi_loopdelayed2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i64 [[N:%.*]], 0
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br i1 [[CMP15]], label [[LOOP:%.*]], label [[END:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT:    [[LPHI_TC:%.*]] = phi float [ [[LS_BC]], [[ENTRY]] ], [ [[LD_BC:%.*]], [[LOOP]] ]
; CHECK-NEXT:    [[LPHI2_TC:%.*]] = phi float [ undef, [[ENTRY]] ], [ [[LPHI_TC]], [[LOOP]] ]
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[END]], label [[LOOP]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ undef, [[ENTRY]] ], [ [[LPHI2_TC]], [[LOOP]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i64 %n, 0
  %ls = load i32, i32* %s, align 4
  br i1 %cmp15, label %loop, label %end

loop:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %lphi = phi i32 [ %ls, %entry ], [ %ld, %loop ]
  %lphi2 = phi i32 [ undef, %entry ], [ %lphi, %loop ]
  %ld = load i32, i32* %d, align 4
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond = icmp eq i64 %iv.next, %n
  br i1 %exitcond, label %end, label %loop

end:
  %phi = phi i32 [ undef, %entry ], [ %lphi2, %loop ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi_loopmore(i32 *%s, i32 *%d, i64 %n) {
; CHECK-LABEL: @convphi_loopmore(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 1
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[IFEND:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    br label [[IFEND]]
; CHECK:       ifend:
; CHECK-NEXT:    [[PHI1_TC:%.*]] = phi float [ [[LD_BC]], [[THEN]] ], [ [[LS_BC]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i64 [[N]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[LOOP:%.*]], label [[END:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[IFEND]] ], [ [[IV_NEXT:%.*]], [[LOOPEND:%.*]] ]
; CHECK-NEXT:    [[PHI2_TC:%.*]] = phi float [ [[PHI1_TC]], [[IFEND]] ], [ [[PHI3_TC:%.*]], [[LOOPEND]] ]
; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[N]], 1
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOPTHEN:%.*]], label [[LOOPEND]]
; CHECK:       loopthen:
; CHECK-NEXT:    [[LL:%.*]] = load i32, i32* [[D]], align 4
; CHECK-NEXT:    [[LL_BC:%.*]] = bitcast i32 [[LL]] to float
; CHECK-NEXT:    br label [[LOOPEND]]
; CHECK:       loopend:
; CHECK-NEXT:    [[PHI3_TC]] = phi float [ [[LL_BC]], [[LOOPTHEN]] ], [ [[PHI2_TC]], [[LOOP]] ]
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[END]], label [[LOOP]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[PHI1_TC]], [[IFEND]] ], [ [[PHI3_TC]], [[LOOPEND]] ]
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp = icmp eq i64 %n, 1
  %ls = load i32, i32* %s, align 4
  br i1 %cmp, label %then, label %ifend

then:
  %ld = load i32, i32* %d, align 4
  br label %ifend

ifend:
  %phi1 = phi i32 [ %ld, %then ], [ %ls, %entry ]
  %cmp15 = icmp sgt i64 %n, 0
  br i1 %cmp15, label %loop, label %end

loop:
  %iv = phi i64 [ 0, %ifend ], [ %iv.next, %loopend ]
  %phi2 = phi i32 [ %phi1, %ifend ], [ %phi3, %loopend ]
  br i1 %cmp, label %loopthen, label %loopend

loopthen:
  %ll = load i32, i32* %d, align 4
  br label %loopend

loopend:
  %phi3 = phi i32 [ %ll, %loopthen ], [ %phi2, %loop ]
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond = icmp eq i64 %iv.next, %n
  br i1 %exitcond, label %end, label %loop

end:
  %phi = phi i32 [ %phi1, %ifend ], [ %phi3, %loopend ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define void @convphi_stop(i32 *%s, i32 *%d, float *%e, i32 %n) {
; CHECK-LABEL: @convphi_stop(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
; CHECK-NEXT:    store float [[B]], float* [[E:%.*]], align 4
; CHECK-NEXT:    ret void
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load i32, i32* %s, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  store float %b, float* %e, align 4
  ret void
}

define void @convphi_stop2(i32 *%s, i32 *%d, float *%e, i32 %n) {
; CHECK-LABEL: @convphi_stop2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LSB:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LDB:%.*]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[LSB]], [[THEN]] ], [ [[LDB]], [[ELSE]] ]
; CHECK-NEXT:    store float [[PHI]], float* [[E:%.*]], align 4
; CHECK-NEXT:    ret void
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load i32, i32* %s, align 4
  %lsb = bitcast i32 %ls to float
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  %ldb = bitcast i32 %ld to float
  br label %end

end:
  %phi = phi float [ %lsb, %then ], [ %ldb, %else ]
  store float %phi, float* %e, align 4
  ret void
}

define float @convphi_stop3(i32 *%s, i32 *%d, float *%e, i32 %n) {
; CHECK-LABEL: @convphi_stop3(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ELSE]] ]
; CHECK-NEXT:    store float [[PHI_TC]], float* [[E:%.*]], align 4
; CHECK-NEXT:    ret float [[PHI_TC]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load i32, i32* %s, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  store float %b, float* %e, align 4
  ret float %b
}

define void @convphi_stop4(i32 *%s, i32 *%d, float *%e, i32 %n) {
; CHECK-LABEL: @convphi_stop4(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    [[LD_BC:%.*]] = bitcast i32 [[LD]] to float
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[LS_BC:%.*]] = bitcast i32 [[LS]] to float
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI_TC:%.*]] = phi float [ [[LS_BC]], [[THEN]] ], [ [[LD_BC]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[N]], 0
; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[PHI_TC]] to i32
; CHECK-NEXT:    store i32 [[BC]], i32* [[S]], align 4
; CHECK-NEXT:    br i1 [[TMP0]], label [[THEN2:%.*]], label [[END2:%.*]]
; CHECK:       then2:
; CHECK-NEXT:    [[LF:%.*]] = load float, float* [[E:%.*]], align 4
; CHECK-NEXT:    br label [[END2]]
; CHECK:       end2:
; CHECK-NEXT:    [[PHI2:%.*]] = phi float [ [[PHI_TC]], [[END]] ], [ [[LF]], [[THEN2]] ]
; CHECK-NEXT:    store float [[PHI2]], float* [[E]], align 4
; CHECK-NEXT:    ret void
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  %ld = load i32, i32* %d, align 4
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %entry ]
  %phib = bitcast i32 %phi to float
  store i32 %phi, i32* %s, align 4
  br i1 %cmp15, label %then2, label %end2

then2:
  %lf = load float, float* %e, align 4
  br label %end2

end2:
  %phi2 = phi float [ %phib, %end ], [ %lf, %then2 ]
  store float %phi2, float* %e, align 4
  ret void
}

define float @multiuse(i32 *%s, i32 *%d, i32 %n) {
; CHECK-LABEL: @multiuse(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    [[A:%.*]] = add i32 [[LS]], 2
; CHECK-NEXT:    store i32 [[A]], i32* [[D:%.*]], align 4
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
; CHECK-NEXT:    ret float [[B]]
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load i32, i32* %s, align 4
  %a = add i32 %ls, 2
  store i32 %a, i32* %d, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define float @convphi_volatile(i32 *%s, i32 *%d, i32 %n) {
; CHECK-LABEL: @convphi_volatile(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
; CHECK-NEXT:    ret float [[B]]
;
; DEBUG-LABEL: @convphi_volatile(
; DEBUG-NEXT:  entry:
; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !358
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !353, metadata !DIExpression()), !dbg !358
; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !359
; DEBUG:       then:
; DEBUG-NEXT:    [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4, !dbg !360
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !354, metadata !DIExpression()), !dbg !360
; DEBUG-NEXT:    br label [[END:%.*]], !dbg !361
; DEBUG:       else:
; DEBUG-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !362
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LD]], metadata !355, metadata !DIExpression()), !dbg !362
; DEBUG-NEXT:    br label [[END]], !dbg !363
; DEBUG:       end:
; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !364
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !356, metadata !DIExpression()), !dbg !364
; DEBUG-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !365
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata float [[B]], metadata !357, metadata !DIExpression()), !dbg !365
; DEBUG-NEXT:    ret float [[B]], !dbg !366
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load volatile i32, i32* %s, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define void @convphi_volatile2(i32 *%s, i32 *%d, i32 %n, float %f) {
; CHECK-LABEL: @convphi_volatile2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    store volatile i32 [[PHI]], i32* [[D:%.*]], align 4
; CHECK-NEXT:    ret void
;
; DEBUG-LABEL: @convphi_volatile2(
; DEBUG-NEXT:  entry:
; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !373
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !369, metadata !DIExpression()), !dbg !373
; DEBUG-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !374
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[FB]], metadata !370, metadata !DIExpression()), !dbg !374
; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !375
; DEBUG:       then:
; DEBUG-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !376
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !371, metadata !DIExpression()), !dbg !376
; DEBUG-NEXT:    br label [[END]], !dbg !377
; DEBUG:       end:
; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !378
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !372, metadata !DIExpression()), !dbg !378
; DEBUG-NEXT:    store volatile i32 [[PHI]], i32* [[D:%.*]], align 4, !dbg !379
; DEBUG-NEXT:    ret void, !dbg !380
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  %fb = bitcast float %f to i32
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
  store volatile i32 %phi, i32 *%d
  ret void
}

define float @convphi_atomic(i32 *%s, i32 *%d, i32 %n) {
; CHECK-LABEL: @convphi_atomic(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4
; CHECK-NEXT:    br label [[END:%.*]]
; CHECK:       else:
; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
; CHECK-NEXT:    ret float [[B]]
;
; DEBUG-LABEL: @convphi_atomic(
; DEBUG-NEXT:  entry:
; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !388
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !383, metadata !DIExpression()), !dbg !388
; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !389
; DEBUG:       then:
; DEBUG-NEXT:    [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4, !dbg !390
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !384, metadata !DIExpression()), !dbg !390
; DEBUG-NEXT:    br label [[END:%.*]], !dbg !391
; DEBUG:       else:
; DEBUG-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !392
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LD]], metadata !385, metadata !DIExpression()), !dbg !392
; DEBUG-NEXT:    br label [[END]], !dbg !393
; DEBUG:       end:
; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !394
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !386, metadata !DIExpression()), !dbg !394
; DEBUG-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !395
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata float [[B]], metadata !387, metadata !DIExpression()), !dbg !395
; DEBUG-NEXT:    ret float [[B]], !dbg !396
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  br i1 %cmp15, label %then, label %else

then:
  %ls = load atomic i32, i32* %s acquire, align 4
  br label %end

else:
  %ld = load i32, i32* %d, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
  %b = bitcast i32 %phi to float
  ret float %b
}

define void @convphi_atomic2(i32 *%s, i32 *%d, i32 %n, float %f) {
; CHECK-LABEL: @convphi_atomic2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32
; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK:       then:
; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
; CHECK-NEXT:    br label [[END]]
; CHECK:       end:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4
; CHECK-NEXT:    ret void
;
; DEBUG-LABEL: @convphi_atomic2(
; DEBUG-NEXT:  entry:
; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !403
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !399, metadata !DIExpression()), !dbg !403
; DEBUG-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !404
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[FB]], metadata !400, metadata !DIExpression()), !dbg !404
; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !405
; DEBUG:       then:
; DEBUG-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !406
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !401, metadata !DIExpression()), !dbg !406
; DEBUG-NEXT:    br label [[END]], !dbg !407
; DEBUG:       end:
; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !408
; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !402, metadata !DIExpression()), !dbg !408
; DEBUG-NEXT:    store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4, !dbg !409
; DEBUG-NEXT:    ret void, !dbg !410
;
entry:
  %cmp15 = icmp sgt i32 %n, 0
  %fb = bitcast float %f to i32
  br i1 %cmp15, label %then, label %end

then:
  %ls = load i32, i32* %s, align 4
  br label %end

end:
  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
  store atomic i32 %phi, i32 *%d release, align 4
  ret void
}
